package com.wjw.spring5.aopannotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author wjw
 * @date 2021年11月04日 12:49
 * 增强类
 */
@Component
@Aspect // 生成代理对象
@Order(3)
public class UserProxy {
    // 抽取相同的切入点
    @Pointcut(value = "execution(* com.wjw.spring5.aopannotation.User.add(..))")
    public void commonEntryPoint(){}
    // 前置通知
    @Before("commonEntryPoint()")
    public void before() {
        System.out.println("Before ......");
    }
    // 后置通知(返回通知)
    @AfterReturning("execution(* com.wjw.spring5.aopannotation.User.add(..))")
    public void afterReturning() {
        System.out.println("AfterReturning ......");
    }
    // 异常通知 如果有异常，则后置通知，和环绕后通知不会执行
    @AfterThrowing("execution(* com.wjw.spring5.aopannotation.User.add(..))")
    public void afterThrowing() {
        System.out.println("AfterThrowing异常 ......");
    }
    // 最终通知 一定会执行，类似与 try 语句块的 finally
    @After("execution(* com.wjw.spring5.aopannotation.User.add(..))")
    public void after() {
        System.out.println("After ......");
    }
    // 环绕通知
    @Around("execution(* com.wjw.spring5.aopannotation.User.add(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前 ......");
        joinPoint.proceed(); // 执行目标方法 需要 ProceedingJoinPoint 作为参数
        System.out.println("环绕后 ......");
    }
}
